/*
 * Created on Jul 28, 2005
 *
 */
package sceneInfo;

import java.util.ArrayList;
import java.util.StringTokenizer;
import java.io.Serializable;

import sceneMatch.MatchNode;


/** 
 * @author Kevin Lam
 * @author David Tudino
 * @author Michael Floyd
 *
 */
public class VisualInfo implements Serializable {
	
	private static final long serialVersionUID = 1L;

	//TODO explain this value
	private int	m_time;

	//the message we receive from the server
	private String m_message;
	//the name of our team
	private String teamName;

	//TODO explain what these are
  	private float sceneDist = 0.0f;
	private short nodeNumOffset = 0;
	
	// objects stored in lists for speedy searching as well as the linked-lists, below
	private ArrayList<ObjectInfo> m_objects;				// all objects
	private ArrayList<ObjectInfo> m_ball_list;
	//TODO remove the player list...we already seperate it into team/opp/??
	private ArrayList<ObjectInfo> m_player_list;
	private ArrayList<ObjectInfo> m_teammates_list;
	private ArrayList<ObjectInfo> m_opponents_list;
	private ArrayList<ObjectInfo> m_unknownPlayers_list;
	private ArrayList<ObjectInfo> m_flag_list;
	private ArrayList<ObjectInfo> m_goal_list;
	private ArrayList<ObjectInfo> m_line_list;

	/*
  	// Linked lists for each object type, these linked listes are used
	//for the BPM algorithm
     private BallInfo v_ballList;
     private PlayerInfo v_teammateList;
     private PlayerInfo v_opponentList;
     private PlayerInfo v_unknownPlayerList;
     private GoalInfo v_goalList;
     private FlagInfo v_flagList;
     private LineInfo v_lineList;
      
     //we will put the linked list pointers for each object
     //in an array for easy access
     private ObjectInfo[] v_objList;
     //TODO what it this?
     private MatchNode[] v_lastNodes;
     */
     //When comparing scenes using th BPM, one scene is said to
     //be blue in color. This is done because the sccenes are superimposed
     //and the coloring allows assurance we match an object to an object of
     //another scene (another color)
     private boolean isBlue = true;
     
     	
  	/** Constructs a VisualInfo based on the information received from the
  	 * server and the team name.
  	 * 
  	 * @param info Message from the server
  	 * @param myTeam Team name
  	 */
	public VisualInfo(String info, String myTeam)
	{
		//the message we receive from the server
 		info.trim();
	 	m_message = info;
	 	
	 	//save our team name
		teamName = myTeam;

		//we will initialize the arraylists that will store the
		//objects in this visual info
		m_player_list = new ArrayList<ObjectInfo>();
	   	m_teammates_list = new ArrayList<ObjectInfo>();
	   	m_opponents_list = new ArrayList<ObjectInfo>();
		m_unknownPlayers_list = new ArrayList<ObjectInfo>();
		m_ball_list = new ArrayList<ObjectInfo>();
		m_goal_list = new ArrayList<ObjectInfo>();
		m_line_list = new ArrayList<ObjectInfo>();
		m_flag_list = new ArrayList<ObjectInfo>();
		m_objects = new ArrayList<ObjectInfo>();
	
		/*//the linked lists of each object is empty, because
		//we have not added any objects yet
		v_ballList = null;
	    v_teammateList = null;
	    v_opponentList = null;
	    v_unknownPlayerList = null;
	    v_goalList = null;
	    v_flagList = null;
	    v_lineList = null;
		
	    //store the pointers in an array
	    v_objList = new ObjectInfo[7];
	    v_objList[0] = v_ballList;
	    v_objList[1] = v_teammateList;
	    v_objList[2] = v_opponentList;
	    v_objList[3] = v_unknownPlayerList;
	    v_objList[4] = v_goalList;
	    v_objList[5] = v_flagList;
	    v_objList[6] = v_lineList;
	     
	    v_lastNodes = new MatchNode[7];*/
	}

	   /** Constructs a VisualInfo object based on the message sent by the server,
	    * the team name, and whether they are the blue team(for BPM algorithm)
	    * 
	    * @param info The message from the server
	    * @param myTeam The team name
	    * @param isBlueTeam True if the scene is the blue scene
	    */
	 	public VisualInfo(String info, String myTeam, boolean isBlueTeam)
		{
	 		this(info,myTeam);
	 		this.isBlue = isBlueTeam;
		}
	 	

	// these methods retrieve objects as ArrayLists
	public ArrayList<ObjectInfo> getObjects()
	{
		return m_objects;
	}
	public ArrayList<ObjectInfo> getBallList()
	{
		return m_ball_list;
	}
	public ArrayList<ObjectInfo> getFlagList()
	{
		return m_flag_list;
	}
	public ArrayList<ObjectInfo> getLineList()
	{
		return m_line_list;
	}
	public ArrayList<ObjectInfo> getGoalList()
	{
		return m_goal_list;
	}
	public ArrayList<ObjectInfo> getPlayerList()
	{
		return m_player_list;
	}
	public ArrayList<ObjectInfo> getTeammatesList()
	{
		return m_teammates_list;
	}
	public ArrayList<ObjectInfo> getOpponentsList()
	{
		return m_opponents_list;
	}
	public ArrayList<ObjectInfo> getUnknownPlayersList()
	{
		return m_unknownPlayers_list;
	}


	/*
	//TODO check the quality of everything below this point
	
	public void addBallInfo (BallInfo newBallInfo) {
		if (v_ballList == null) {
			v_ballList = newBallInfo;
			v_ballList.node_number = (short)(1 + nodeNumOffset);
			v_ballList.is_blue = isBlue;
			v_objList[0] = v_ballList;
			m_ball_list.add(newBallInfo);
		} else {
			//v_ballList.addNextNode(newBallInfo);
			newBallInfo.node_number = (short)(v_lastNodes[0].node_number + 1);
			newBallInfo.is_blue = isBlue;
			v_lastNodes[0].next_node = newBallInfo;
		}
		v_lastNodes[0] = newBallInfo;
	}
	
	public void addTeammateInfo (PlayerInfo newPlayerInfo) {
		if (v_teammateList == null) {
			v_teammateList = newPlayerInfo;
			v_teammateList.node_number = (short)(1 + nodeNumOffset);
			v_teammateList.is_blue = isBlue;
			v_objList[1] = v_teammateList;
		} else {
			//v_teammateList.addNextNode(newPlayerInfo);
			newPlayerInfo.node_number = (short)(v_lastNodes[1].node_number + 1);
			newPlayerInfo.is_blue = isBlue;
			v_lastNodes[1].next_node = newPlayerInfo;
		}
		v_lastNodes[1] = newPlayerInfo;
	}
	
	public void addOpponentInfo (PlayerInfo newPlayerInfo) {
		if (v_opponentList == null) {
			v_opponentList = newPlayerInfo;
			v_opponentList.node_number = (short)(1 + nodeNumOffset);
			v_opponentList.is_blue = isBlue;
			v_objList[2] = v_opponentList;
		} else {
			//v_opponentList.addNextNode(newPlayerInfo);
			newPlayerInfo.node_number = (short)(v_lastNodes[2].node_number + 1);
			newPlayerInfo.is_blue = isBlue;
			v_lastNodes[2].next_node = newPlayerInfo;
		}
		v_lastNodes[2] = newPlayerInfo;
	}
	
	public void addUnknownPlayerInfo (PlayerInfo newPlayerInfo) {
		if (v_unknownPlayerList == null) {
			v_unknownPlayerList = newPlayerInfo;
			v_unknownPlayerList.node_number = (short)(1 + nodeNumOffset);
			v_unknownPlayerList.is_blue = isBlue;
			v_objList[3] = v_unknownPlayerList;
		} else {
			//v_unknownPlayerList.addNextNode(newPlayerInfo);
			newPlayerInfo.node_number = (short)(v_lastNodes[3].node_number + 1);
			newPlayerInfo.is_blue = isBlue;
			v_lastNodes[3].next_node = newPlayerInfo;
		}
		v_lastNodes[3] = newPlayerInfo;
	}

	public void addGoalInfo (GoalInfo newGoalInfo) {
		if (v_goalList == null) {
			v_goalList = newGoalInfo;
			v_goalList.node_number = (short)(1 + nodeNumOffset);
			v_goalList.is_blue = isBlue;
			v_objList[4] = v_goalList;
			m_goal_list.add(newGoalInfo);
		} else {
			//v_goalList.addNextNode(newGoalInfo);
			newGoalInfo.node_number = (short)(v_lastNodes[4].node_number + 1);
			newGoalInfo.is_blue = isBlue;
			v_lastNodes[4].next_node = newGoalInfo;
		}
		v_lastNodes[4] = newGoalInfo;
	}
	
	public void addFlagInfo (FlagInfo newFlagInfo) {
		if (v_flagList == null) {
			v_flagList = newFlagInfo;
			v_flagList.node_number = (short)(1 + nodeNumOffset);
			v_flagList.is_blue = isBlue;
			v_objList[5] = v_flagList;
		} else {
			//v_flagList.addNextNode(newFlagInfo);
			newFlagInfo.node_number = (short)(v_lastNodes[5].node_number + 1);
			newFlagInfo.is_blue = isBlue;
			v_lastNodes[5].next_node = newFlagInfo;
		}
		v_lastNodes[5] = newFlagInfo;
	}
	
	public void addLineInfo (LineInfo newLineInfo) {
		if (v_lineList == null) {
			v_lineList = newLineInfo;
			v_lineList.node_number = (short)(1 + nodeNumOffset);
			v_lineList.is_blue = isBlue;
			v_objList[6] = v_lineList;
		} else {
			//v_lineList.addNextNode(newLineInfo);
			newLineInfo.node_number = (short)(v_lastNodes[6].node_number + 1);
			newLineInfo.is_blue = isBlue;
			v_lastNodes[6].next_node = newLineInfo;
		}
		v_lastNodes[6] = newLineInfo;
	}
	*/
	
	public int getTime()
	{
		return m_time;
	}
	
/*
	// these methods return the head object of each linked-list
	public BallInfo getBallInfo () {
		return v_ballList;
	}
	
	public PlayerInfo getTeammateInfo () {
		return v_teammateList;
	}
	
	public PlayerInfo getOpponentInfo () {
		return v_opponentList;
	}
	
	public PlayerInfo getUnknownPlayerInfo () {
		return v_unknownPlayerList;
	}

	public GoalInfo getGoalInfo () {
		return v_goalList;
	}
	
	public FlagInfo getFlagInfo () {
		return v_flagList;
	}
	
	public LineInfo getLineInfo () {
		return v_lineList;
	}
	
	public ObjectInfo[] getObjectList () {
		return v_objList;
	}
	
*/
	public void setNodeOffset (short offset) {
		nodeNumOffset = offset;
	}
	
	/**
	 * This method will return the selected set of objects, with the
	 * new set appended to the end of the linked list. The listToAppend
	 * parameter is the first node of the second linked list of objects.
	 * 
	 * @param lstIndex The index of the object set
	 * @param listToAppend The first node of the linked list to append
	 * @return The first node of the original linked list, for object[lstIndex]
	 * /
	public MatchNode appendList (int lstIndex, MatchNode listToAppend) {
		v_lastNodes[lstIndex].next_node = listToAppend;
		return v_objList[lstIndex];
	}
	
	/**
	 * This method will break the linked list. After calling this method, the
	 * list specified by the index will be in its original state.
	 * 
	 * @param lstIndex The index of the list to un-Append
	 * /
	public void unAppendList (int lstIndex) {
		v_lastNodes[lstIndex].next_node = null;
	}
	
	* /
	public void resetNodeList () {
		MatchNode tmpNode;
		
		for (int i = 0; i < 7; i++) {
			if (v_objList[i] != null) {
				//v_objList[i].resetNode();
				tmpNode = null;
				
				for (tmpNode = v_objList[i]; tmpNode != null; tmpNode = tmpNode.next_node) {
					tmpNode.tight_towards_tree_root = null;
					tmpNode.tight_away_from_tree_root = null;
					tmpNode.sibling = null;
					tmpNode.counted = false;
					tmpNode.spouse = null;
					tmpNode.radius = 0.0f;
				}
			}	
		}
	}*/
	
	//---------------------------------------------------------------------------
	// This function parses visual information from the server
	public void parse()
	{
		String token = null;
		ObjectInfo objInfo;
		
		float scale = 5; //10;
		
		// for the arraylists
		m_player_list.clear();
		m_teammates_list.clear();
		m_opponents_list.clear();
		m_unknownPlayers_list.clear();
		m_ball_list.clear();
		m_goal_list.clear();
		m_line_list.clear();
		m_flag_list.clear();
         
        /* //for the linked lists
   		 v_ballList = null;
	     v_teammateList = null;
	     v_opponentList = null;
	     v_unknownPlayerList = null;
	     v_goalList = null;
	     v_flagList = null;
	     v_lineList = null;*/
	     
	     float tmp_distance, tmp_direction, tmp_x, tmp_y;
	     

		StringTokenizer m_tokenizer = new StringTokenizer(m_message,"() ", true);

		//try
		//{
			m_tokenizer.nextToken();	// '('
      		// Don't parse information if it's not 'see' information
			if( m_tokenizer.nextToken().compareTo("see") != 0 )
				return;

			m_tokenizer.nextToken();	// ' '
			m_time = Integer.parseInt( m_tokenizer.nextToken() ); // TIME
			m_tokenizer.nextToken();	// ' '
			token = m_tokenizer.nextToken();

			while(token.compareTo("(") == 0)// '('
			{
        			// Create soccer object for reference - can be player, ball, flag or line
				objInfo = createNewObject(m_tokenizer);

                        if (objInfo.getType().startsWith("player")) {

						    //m_player_list.addElement(objInfo);
							try
							{
								//System.out.println("Player team: '" + ((PlayerInfo)objInfo).getTeamName() + "' My team: '" + teamName + "'");
								if ((teamName == null) || (teamName.length() == 0)) // I don't know my own team 
								{
									//addUnknownPlayerInfo((PlayerInfo)objInfo);		// add to linked list
									m_unknownPlayers_list.add((PlayerInfo) objInfo);// add to arraylist
									m_objects.add(objInfo);							// add to master object list
								}
								else if (teamName.equals(((PlayerInfo) objInfo).getTeamName()))
								{
									// System.out.println("Adding to teammate list...");
									//addTeammateInfo((PlayerInfo)objInfo);
									m_teammates_list.add((PlayerInfo) objInfo);		// add to arraylist
									m_objects.add(objInfo);							// add to master object list

								}
								else if (((PlayerInfo) objInfo).getTeamName().length() == 0)
								{
									// System.out.println("Adding to unknown list...");
									//addUnknownPlayerInfo((PlayerInfo)objInfo);
									m_unknownPlayers_list.add((PlayerInfo) objInfo);// add to arraylist
									m_objects.add(objInfo);							// add to master object list

								}
								else
								{
									// System.out.println("Adding to Opponent list...");
									//addOpponentInfo((PlayerInfo)objInfo);
									m_opponents_list.add((PlayerInfo) objInfo);		// add to arraylist
									m_objects.add(objInfo);							// add to master object list

									//if (m_opponents_list.size() >= 12)
									//{
									//	System.out.println("ERROR!!  More than 11 opponents on the scene!!!");
									//}
								}
							}
							catch (Exception e)
							{
								//System.out.println("Player parsing error.");
							}
                        } 
                        else if (objInfo.getType().startsWith("ball")) {

                        	//addBallInfo((BallInfo)objInfo);
							m_ball_list.add((BallInfo) objInfo);			// add to arraylist
							m_objects.add(objInfo);							// add to master object list

                        }
                        else if (objInfo.getType().startsWith("goal")) {

                        	//addGoalInfo((GoalInfo)objInfo);
							m_goal_list.add((GoalInfo) objInfo);			// add to arraylist
							m_objects.add(objInfo);							// add to master object list

                        }
                        else if (objInfo.getType().startsWith("line")) {
							m_line_list.add((LineInfo) objInfo);			// add to arraylist
							m_objects.add(objInfo);							// add to master object list

                        	//addLineInfo((LineInfo)objInfo);
                        }
                        else if (objInfo.getType().startsWith("flag")) {
							m_flag_list.add((FlagInfo) objInfo);			// add to arraylist
							m_objects.add(objInfo);							// add to master object list

                        	//addFlagInfo((FlagInfo)objInfo);
                        }

				token = m_tokenizer.nextToken();
				if( token.compareTo(")") == 0 )
				{
					token = m_tokenizer.nextToken();
					if(token.compareTo(" ") == 0) token = m_tokenizer.nextToken();
					continue;
				}

				token = m_tokenizer.nextToken();
        			// Get object's approximate distance from agent - actual distance
        			// becomes more difficult to determine as the distance increases
				//objInfo.m_distance = Float.valueOf(token).floatValue();
				tmp_distance = Float.valueOf(token).floatValue();
				token = m_tokenizer.nextToken();

				if( token.compareTo(")") == 0 )
				{
					token = m_tokenizer.nextToken();
					if(token.compareTo(" ") == 0) token = m_tokenizer.nextToken();
					continue;
				}

		        	// Get object direction relative to the agent
				//objInfo.m_direction = Float.valueOf(m_tokenizer.nextToken()).floatValue();
				tmp_direction = Float.valueOf(m_tokenizer.nextToken()).floatValue();
				token = m_tokenizer.nextToken();

				
				//now that we have the distance and direction, calculate the
				//x,y position of the item
				//code taken from calculatePoint(...) method in the classifier
				//PlayerCanvas.java.
			    tmp_x =  scale * (float) (tmp_distance * Math.sin(Math.toRadians(tmp_direction)));
			    tmp_y =  scale * (float) (-1 * tmp_distance * Math.cos(Math.toRadians(tmp_direction)));

			    //next part seems10 to adjust points into visible window.. ignore for now
			    //int x = relative_x + user_x -(width/2);
			    //int y = relative_y + user_y -(width/2);
			    //user_x, user_y = 500, width = 500:  
			    //user_x - (width/2) = 500 - (500/2) = 250
			    tmp_x = tmp_x + 300;
			    tmp_y = tmp_y + 500;
			    
			    //write all these to the object
			    objInfo.setDistance(tmp_distance);
			    objInfo.setDirection(tmp_direction);
				objInfo.x = tmp_x;
				objInfo.y = tmp_y;
				
				//System.out.println("distance: " + tmp_distance + ", direction: " + tmp_direction + ", x: " + tmp_x + ", y: " + tmp_y);
				
				if( token.compareTo(")") == 0 )
				{
					token = m_tokenizer.nextToken();
					if(token.compareTo(" ") == 0) token = m_tokenizer.nextToken();
					continue;
				}

        			// Get the distance change since last 'see' message
				objInfo.setDistChange(Float.valueOf(m_tokenizer.nextToken()).floatValue());
				try{
				token = m_tokenizer.nextToken();
				} catch(Exception e){
					System.err.println("token is :"+token+":");
				}

				if( token.compareTo(")") == 0 )
				{
					token = m_tokenizer.nextToken();
					if(token.compareTo(" ") == 0) token = m_tokenizer.nextToken();
					continue;
				}

        			// Get direction change since last 'see' message
				objInfo.setDirChange(Float.valueOf(m_tokenizer.nextToken()).floatValue());
				token = m_tokenizer.nextToken();

				if( token.compareTo(")") == 0 )
				{
					token = m_tokenizer.nextToken();
					if(token.compareTo(" ") == 0) token = m_tokenizer.nextToken();
					continue;
				}

				// Player's bodyDir parameter
		        	((PlayerInfo)(objInfo)).m_bodyDir = Float.valueOf(m_tokenizer.nextToken()).floatValue();
				token = m_tokenizer.nextToken();

				if( token.compareTo(")") == 0 )
				{
					token = m_tokenizer.nextToken();
					if(token.compareTo(" ") == 0) token = m_tokenizer.nextToken();
					continue;
				}

				// Player's headDir parameter
        			((PlayerInfo)(objInfo)).m_headDir = Float.valueOf(m_tokenizer.nextToken()).floatValue();

				token = m_tokenizer.nextToken();
				token = m_tokenizer.nextToken();
				if(token.compareTo(" ") == 0) token = m_tokenizer.nextToken();
			}
		/*}
		catch(Exception e)
		{
			System.out.println("Error parsing see information!");
			e.printStackTrace();
			/*System.out.println(token);
			while( m_tokenizer.hasMoreTokens() )
      		{
        			token = m_tokenizer.nextToken();
        			System.out.print(token);//m_tokenizer.nextToken());
      		}
            System.out.println(m_message);* /
//			System.out.println("");
		}*/
	}

	//===========================================================================
	// Private implementations

	//---------------------------------------------------------------------------
	// This function creates new object based on the see message sent from the
	// server
	private ObjectInfo createNewObject(StringTokenizer m_tokenizer)
	{
		String token = null;
		ObjectInfo objInfo = null;

		m_tokenizer.nextToken();			// '('
		token = m_tokenizer.nextToken();
		if(token.compareTo("player") == 0 || token.compareTo("p") == 0)  // player object
		{
			String team = new String();
			int uniformNumber = 0;
            boolean goalie = false;
			token = m_tokenizer.nextToken();	// ' '
			if(token.compareTo(" ") == 0)
			{
				team = m_tokenizer.nextToken();	// teamname
				token = m_tokenizer.nextToken();// ' '
				if(token.compareTo(" ") == 0)
        			{
		          		// uniform number
                              token = m_tokenizer.nextToken();
          				uniformNumber = Integer.parseInt(token);
                              token = m_tokenizer.nextToken();
                              if(token.compareTo(" ") == 0)
                              {
                                  // Player is a goalie?
                                  token = m_tokenizer.nextToken();
                                  if(token.compareTo("goalie") == 0)
                                  {
                                      goalie = true;
                                  }
                              }
        			}
			}
			objInfo = new PlayerInfo(team, uniformNumber, goalie);
		}
		else if(token.compareTo("goal") == 0 || token.compareTo("g") == 0) // goal object
		{
			token = m_tokenizer.nextToken();	// space
			if(token.compareTo(" ") == 0) token = m_tokenizer.nextToken();	// side
			objInfo = new GoalInfo(token.charAt(0));
			//System.out.println("found goal " + token);
		}
		else if(token.compareTo("ball") == 0 || token.compareTo("b") == 0) // ball object
		{
			objInfo = new BallInfo();
		}
		else if(token.compareTo("flag") == 0 || token.compareTo("f") == 0) // flag object
		{
			char type = ' ';
			char pos1 = ' ';
			char pos2 = ' ';
			int num = 0;
			boolean out = true;

			token = m_tokenizer.nextToken();	// space
			token = m_tokenizer.nextToken();	// p or g or [l|c|r] or [b|t]
			if(( token.compareTo("p") == 0 )||( token.compareTo("g") == 0 ))
			{
				type = token.charAt(0);
				token = m_tokenizer.nextToken();	// space
				token = m_tokenizer.nextToken();	// [l|r]
				pos1 = token.charAt(0);
				token = m_tokenizer.nextToken();	// space
				token = m_tokenizer.nextToken();	// [t|c|b]
				pos2 = token.charAt(0);
				out = false;
			}
			else if(( token.compareTo("l") == 0 )||( token.compareTo("r") == 0 ))
			{
				pos1 = token.charAt(0);
				token = m_tokenizer.nextToken();	// space
				token = m_tokenizer.nextToken();	// [t|b] or 0
				pos2 = token.charAt(0);

				if (pos2 == '0')
				{
					num=0;
					pos2=' ';
					out=true;
				}
				else
				{
					token = m_tokenizer.nextToken(); 	// space or )

					if ( token.compareTo(")") == 0 ) out=false;
					else
					{
						num = Integer.parseInt( m_tokenizer.nextToken() );
						out=true;
					}
				}
			}
			else if( token.compareTo("c") == 0 )
			{
				pos1 = token.charAt(0);
				token = m_tokenizer.nextToken();	// ) or space
				if ( token.compareTo(")") != 0)
				{
					token = m_tokenizer.nextToken();	// [t|b]
					pos2 = token.charAt(0);
				}
				out=false;
			}
			else if(( token.compareTo("b") == 0 )||( token.compareTo("t") == 0 ))
			{
				pos1 = token.charAt(0);
				token = m_tokenizer.nextToken();	// space
				token = m_tokenizer.nextToken();	// [r|l] or 0
				pos2 = token.charAt(0);

				if ( pos2 == '0')
				{
					pos2=' ';
					num=0;
				}
				else
				{
					token = m_tokenizer.nextToken();			// space
					num = Integer.parseInt(m_tokenizer.nextToken());	// number
					token = m_tokenizer.nextToken();			// )
				}
				out=true;
			}

      		String flagType = "flag";
      		if (type != ' ') flagType = flagType + " " + type;
      		if (pos1 != ' ') flagType = flagType + " " + pos1;
      		if (pos2 != ' ') flagType = flagType + " " + pos2;

      		// Implementing flags like this, allows one to specifically find a
      		// particular flag (i.e. "flag c", or "flag p l t")
			objInfo = new FlagInfo(flagType, type, pos1, pos2, num, out);
		}
		else if(token.compareTo("line") == 0 || token.compareTo("l") == 0) // line object
		{
			token = m_tokenizer.nextToken();	// space
			token = m_tokenizer.nextToken();	// [l|r|t|b]
			objInfo = new LineInfo(token.charAt(0));
		}
		else if(token.compareTo("Player") == 0 || token.compareTo("P") == 0)
		{
			objInfo = new PlayerInfo();
		}
		else if(token.compareTo("Goal") == 0 || token.compareTo("G") == 0)
		{
			objInfo = new GoalInfo();
		}
		else if(token.compareTo("Ball") == 0 || token.compareTo("B") == 0)
		{
			objInfo = new BallInfo();
		}
		else if(token.compareTo("Flag") == 0 || token.compareTo("F") == 0)
		{
			objInfo = new FlagInfo();
		}
		else if(token.compareTo("Line") == 0 || token.compareTo("L") == 0)
		{
			objInfo = new LineInfo();
		}

    		while (token.compareTo(")") != 0)
    		{
      		token = m_tokenizer.nextToken();
    		}

		return objInfo;
	}
	

	public float getSceneDist () {
		return sceneDist;
	}
	
	public void setSceneDist (float dist) {
		sceneDist = dist;
	}
	
	public boolean isBlue () {
		return isBlue;
	}
}
